using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml;

using miciv;
using micivCore.Player;
using System.IO;
using micivCore.DataSource;
using miciv.Misc;

namespace micivCore.Level
{
    public class LevelManager
    {
        protected Hashtable m_htblLevels;
        protected Hashtable m_htblSettings;
        protected LevelConfigDataSource m_levelConfigDataSource;

        protected CoreContext m_coreContext;
        public CoreContext CoreContext
        {
            get
            {
                return this.m_coreContext;
            }
        }

        protected LevelSettings m_currentSettings;
        public LevelSettings CurrentSettings
        {
            get
            {
                return this.m_currentSettings;
            }
        }

        protected List<PlayerDescription> m_lstPlayerDescs;
        public List<PlayerDescription> PlayerDescs
        {
            get
            {
                return this.m_lstPlayerDescs;
            }
        }

        public LevelManager(CoreContext _coreContext)
        {
            this.m_coreContext = _coreContext;
            this.m_htblLevels = new Hashtable();
            this.m_htblSettings = new Hashtable();
            this.m_levelConfigDataSource = new LevelConfigDataSource();
            this.CoreContext.GetData<DataSourceManager>("DataSourceManager").Add("partyinfo", this.m_levelConfigDataSource);
            this.CoreContext.GetData<DataSourceManager>("DataSourceManager").Add("partyplayerlist", this.m_levelConfigDataSource);

            this.m_lstPlayerDescs = new List<PlayerDescription>();
            this.m_lstPlayerDescs.Add(new PlayerDescription());
            this.m_lstPlayerDescs[0].PlayerType = PlayerType.LOCAL;
        }

        public void Update()
        {
        }

        public Level LoadLevel(string _strLocation)
        {
            if (false == this.m_htblLevels.ContainsKey(_strLocation))
            {
                CoreManager coreManager = this.m_coreContext.CoreManager;
                _strLocation = coreManager.GetExistingFile(_strLocation);
                XmlDocument xmlDoc = coreManager.LoadXml(_strLocation, false);
                Level level = new Level(this.m_coreContext);
                if (false != level.Initialize(xmlDoc.DocumentElement.SelectSingleNode("level") as XmlElement, this.m_lstPlayerDescs))
                {
                    this.m_htblLevels.Add(_strLocation, level);
                }
            }
            return GetLevel(_strLocation);
        }

        public void UnloadLevel(string _strLocation)
        {
            if (false != this.m_htblLevels.ContainsKey(_strLocation))
            {
                Level level = this.m_htblLevels[_strLocation] as Level;
                level.Release();
                this.m_htblLevels.Remove(_strLocation);
            }
        }

        public Level GetLevel(string _strLocation)
        {
            if (false != this.m_htblLevels.ContainsKey(_strLocation))
            {
                return this.m_htblLevels[_strLocation] as Level;
            }
            return null;
        }

        public bool LoadSettings(string _strLocation)
        {
            if (false == this.m_htblSettings.ContainsKey(_strLocation))
            {
                CoreManager coreManager = this.m_coreContext.CoreManager;
                _strLocation = coreManager.GetExistingFile(_strLocation);
                XmlDocument xmlDoc = coreManager.LoadXml(_strLocation, false);
                LevelSettings settings = new LevelSettings(this);
                XmlElement xmlSettings = xmlDoc.DocumentElement.SelectSingleNode("level/settings") as XmlElement;
                if (false != settings.Initialize(xmlSettings))
                {
                    XmlAttribute attrID = xmlDoc.DocumentElement.SelectSingleNode("level/@id") as XmlAttribute;
                    settings.LevelName = attrID.Value;
                    settings.LevelLocation = _strLocation;
                    this.m_htblSettings.Add(_strLocation, settings);
                }
            }
            this.m_currentSettings = this.m_htblSettings[_strLocation] as LevelSettings;
            this.m_levelConfigDataSource.LevelSettings = this.m_currentSettings;
            return (null != this.m_currentSettings);
        }

        public void SetLocalPlayerNickname(string _strNickName)
        {
            this.m_lstPlayerDescs[0].NickName = _strNickName;
        }

        public Level LoadLevelFromCurrentSettings()
        {
            if (null != this.CurrentSettings)
            {
                return this.LoadLevel(this.CurrentSettings.LevelLocation);
            }
            return null;
        }
    }
}
